package tr.gov.tubitak.uekae.esya.api.cades.example.attributes;

import com.objsys.asn1j.runtime.Asn1ObjectIdentifier;
import junit.framework.TestCase;
import tr.gov.tubitak.uekae.esya.api.asn.cms.EAttribute;
import tr.gov.tubitak.uekae.esya.api.asn.cms.EContentHints;
import tr.gov.tubitak.uekae.esya.api.asn.cms.ESignerLocation;
import tr.gov.tubitak.uekae.esya.api.asn.x509.ECertificate;
import tr.gov.tubitak.uekae.esya.api.cades.example.testconstans.TestConstants;
import tr.gov.tubitak.uekae.esya.api.cmssignature.ISignable;
import tr.gov.tubitak.uekae.esya.api.cmssignature.SignableByteArray;
import tr.gov.tubitak.uekae.esya.api.cmssignature.attribute.*;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.BaseSignedData;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.ESignatureType;
import tr.gov.tubitak.uekae.esya.api.cmssignature.signature.Signer;
import tr.gov.tubitak.uekae.esya.api.common.crypto.BaseSigner;
import tr.gov.tubitak.uekae.esya.api.infra.tsclient.TSSettings;
import tr.gov.tubitak.uekae.esya.api.smartcard.example.SmartCardManager;

import java.util.*;

public class AttributeTest extends TestCase
{
	public void test1() throws Exception
	{
		BaseSignedData bs = new BaseSignedData();
		
		ISignable content = new SignableByteArray("test".getBytes());
		TSSettings tsSettings = TestConstants.getTSSettings();
		
		//add content which will be signed
		bs.addContent(content);
		
		Calendar signingTimeAttr = Calendar.getInstance();
						
		EContentHints chAttr = new EContentHints("text/plain", new Asn1ObjectIdentifier(new int[]{1, 2, 840, 113549, 1, 7 ,1 }));
		
		//Specified attributes are optional,add them to optional attributes list
		List<IAttribute> optionalAttributes = new ArrayList<IAttribute>();
		optionalAttributes.add(new SigningTimeAttr(signingTimeAttr));
		optionalAttributes.add(new SignerLocationAttr("TURKEY", "KOCAELİ", new String[]{"TUBITAK UEKAE","GEBZE"}));
		optionalAttributes.add(new CommitmentTypeIndicationAttr(CommitmentType.CREATION));
		optionalAttributes.add(new ContentHintsAttr(chAttr));
		optionalAttributes.add(new ContentIdentifierAttr("PL123456789".getBytes("ASCII")));
		optionalAttributes.add(new ContentTimeStampAttr());
						
		//create parameters necessary for signature creation
		HashMap<String, Object> params = new HashMap<String, Object>();
		
		params.put(EParameters.P_VALIDATE_CERTIFICATE_BEFORE_SIGNING, false);
		
		//parameters for ContentTimeStamp attribute
		params.put(EParameters.P_TSS_INFO, tsSettings);
		
		ECertificate cert = SmartCardManager.getInstance().getSignatureCertificate(false, true);
		BaseSigner signer = SmartCardManager.getInstance().getSigner(TestConstants.getPIN(), cert);
			
		//add signer
		bs.addSigner(ESignatureType.TYPE_BES, cert, signer, optionalAttributes, params);
		
		byte [] encoded = bs.getEncoded();
				
		BaseSignedData bsController = new BaseSignedData(encoded);
		Signer aSigner = bsController.getSignerList().get(0);
		List<EAttribute> attrs ;
		
		attrs = aSigner.getAttribute(SigningTimeAttr.OID);
		Calendar st = SigningTimeAttr.toTime(attrs.get(0));
		//because of fraction, it is not exactly equal
		assertEquals(true, (signingTimeAttr.getTimeInMillis()-st.getTimeInMillis()) < 1000);
		
		attrs = aSigner.getAttribute(SignerLocationAttr.OID);
		ESignerLocation sl = SignerLocationAttr.toSignerLocation(attrs.get(0));
		assertEquals("TURKEY", sl.getCountry());
		assertEquals("KOCAELİ", sl.getLocalityName());
		assertEquals(true, Arrays.equals(new String[]{"TUBITAK UEKAE","GEBZE"}, sl.getPostalAddress()));

		attrs = aSigner.getAttribute(ContentHintsAttr.OID);
		EContentHints ch = ContentHintsAttr.toContentHints(attrs.get(0));
		assertEquals(true, ch.equals(chAttr));
		
		attrs = aSigner.getAttribute(ContentIdentifierAttr.OID);
		byte [] ci = ContentIdentifierAttr.toIdentifier(attrs.get(0));
		assertEquals(true, Arrays.equals(ci, "PL123456789".getBytes("ASCII")));
		
		attrs = aSigner.getAttribute(CommitmentTypeIndicationAttr.OID);
		CommitmentType ct = CommitmentTypeIndicationAttr.toCommitmentType(attrs.get(0));
		assertEquals(CommitmentType.CREATION, ct);
		
		attrs = aSigner.getAttribute(ContentTimeStampAttr.OID);
		Calendar cal = ContentTimeStampAttr.toTime(attrs.get(0));
		Calendar now = Calendar.getInstance();
		if(now.compareTo(cal) < 0)
			throw new Exception("ContentTimeStampAttr error");
		System.out.println("ok");
	}
}
